package com.xdkj.controller;

import com.xdkj.utils.MinioUtil;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.*;
import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * @author joke
 * @version 1.0
 * @date 2021/11/25-22:11
 */
@Controller
public class FileUploadController {

    /**
     * 上传单个文件
     *
     * @param file 文件
     * @return {@link String}
     */
    @PostMapping("/upload")
    @ResponseBody
    public String upload(MultipartFile file) {
        System.out.println("-------------fileUpload------------");
        String url = "";
        try {
            String fileName = file.getOriginalFilename();
            String newFileName = UUID.randomUUID().toString().replace("-", "") +
                    fileName.substring(fileName.indexOf("."), fileName.length());
            MinioClient minioClient = MinioUtil.getClient();
            InputStream inputStream = file.getInputStream();
            minioClient.putObject(
                    PutObjectArgs.builder().
                            bucket("xdkj-edu")
                            .object(newFileName)
                            .stream(inputStream, file.getSize(), -1)
                            .contentType(file.getContentType())
                            .build());
            url = MinioUtil.HOST + "/" + MinioUtil.BUCKET + "/" + newFileName;
            System.out.println(url);
            inputStream.close();
        } catch (ErrorResponseException e) {
            e.printStackTrace();
        } catch (InsufficientDataException e) {
            e.printStackTrace();
        } catch (InternalException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (XmlParserException e) {
            e.printStackTrace();
        }
        return url;
    }

    /**
     * 上传文件
     *
     * @param multipartFile 多部分文件
     * @return {@link List}<{@link String}>
     */
    @PostMapping("/uploadFiles")
    @ResponseBody
    public List<String> uploadFiles(@RequestParam(name = "multipartFile") MultipartFile[] multipartFile) {
        System.out.println("-------------fileUpload------------");
        List<String> names = new ArrayList<>(multipartFile.length);
        MinioClient minioClient = MinioUtil.getClient();
        for (MultipartFile file : multipartFile) {
            String fileName = file.getOriginalFilename();
            String newFileName = UUID.randomUUID().toString().replace("-", "") +
                    fileName.substring(fileName.indexOf("."), fileName.length());
            InputStream in = null;
            try {
                in = file.getInputStream();
                minioClient.putObject(
                        PutObjectArgs.builder().
                                bucket(MinioUtil.BUCKET)
                                .object(newFileName)
                                .stream(in, file.getSize(), -1)
                                .contentType(file.getContentType())
                                .build());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            names.add(newFileName);
        }
        return names;
    }

    /**
     * 下载文件
     *
     * @param fileName 文件名称
     * @return {@link ResponseEntity}<{@link byte[]}>
     */
    @GetMapping("/downloadFile")
    public ResponseEntity<byte[]> download(@RequestParam String fileName) {
        ResponseEntity<byte[]> responseEntity = null;
        InputStream in = null;
        ByteArrayOutputStream out = null;
        MinioClient minioClient = MinioUtil.getClient();
        try {
            in = minioClient.getObject(GetObjectArgs.builder()
                    .bucket(MinioUtil.BUCKET)
                    .object(fileName)
                    .build());
            out = new ByteArrayOutputStream();
            IOUtils.copy(in, out);
            //封装返回值
            byte[] bytes = out.toByteArray();
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName));
            headers.setContentLength(bytes.length);
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setAccessControlExposeHeaders(Arrays.asList("*"));
            responseEntity = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return responseEntity;
    }

}
